local BLOCK_DATA = { full = { { size = Vector3.one * 3, offset = Vector3.new() } }, half = { { size = Vector3.new(3, 1.5, 3), offset = Vector3.new(0, -0.75, 0), }, { size = Vector3.new(3, 3, 3), offset = Vector3.new(), hidden = true }, }, stair = { { size = Vector3.new(3, 1.5, 3), offset = Vector3.new(0, -0.75, 0), }, { size = Vector3.new(1.5, 1.5, 3), offset = Vector3.new(0.75, 0.75, 0), }, }, corner_stair = { { size = Vector3.new(3, 1.5, 3), offset = Vector3.new(0, -0.75, 0), }, { size = Vector3.new(1.5, 1.5, 1.5), offset = Vector3.new(0.75, 0.75, 0.75), }, }, } local BLOCK_TEXTURES = { oak_block = 5625184464, oak_log = { _DEFAULT = 3258599312, Top = 3595694398, Bottom = 3595694398, }, wood_door = { _TRANS = true, _MESH = { size = Vector3.new(1, 1, 0.1), offset = Vector3.new(0, 0, -1.35) }, _SIZE = Vector3.new(1, 2, 1), Left = {7375901941, u = 4, v = 4}, Right = {7375901941, u = 4, v = 4}, Top = {7375901941, u = 4, v = 4}, Bottom = {7375901941, u = 4, v = 4}, Front = {7375888920, decal = true}, Back = {7375901941, decal = true}, }, glass_block = { _DEFAULT = 4722585572, _TRANS = true, }, cobblestone = 5003953441 } local block_cache = {} function new_block(blockmesh, position, rotation, texture) position = Vector3.new(math.round(position.X / 3) * 3, math.round(position.Y / 3) * 3, math.round(position.Z / 3) * 3) local block = Instance.new("Model") for i = 1, #blockmesh do local partdata = blockmesh[i] local part = Instance.new("Part") part.Anchored = true part.CanTouch = false part.Transparency = partdata.hidden and 1 or 0 part.Size = partdata.size part.Position = partdata.offset part.Parent = block part:SetAttribute("BLOCK_MESH_PART", true) if texture and not partdata.hidden then local texture_type = typeof(texture) if texture_type == "number" then for _, normal in Enum.NormalId:GetEnumItems() do local new = Instance.new("Texture") new.StudsPerTileU = 3 new.StudsPerTileV = 3 new.Face = normal new.Texture = `rbxassetid://{texture}` new.Parent = part end elseif texture_type == "table" then if texture._TRANS then part.Transparency = 1 end if texture._SIZE then part.Size *= texture._SIZE end if texture._MESH then local mesh = Instance.new("SpecialMesh") mesh.MeshType = Enum.MeshType.Brick mesh.Scale = texture._MESH.size mesh.Offset = texture._MESH.offset mesh.Parent = part end for face_index, normal in Enum.NormalId:GetEnumItems() do local texture_face = texture[normal.Name] or texture._DEFAULT or 9094483835 local texture_face_type = typeof(texture_face) if texture_face_type == "number" then local new = Instance.new("Texture") new.StudsPerTileU = 3 new.StudsPerTileV = 3 new.Face = normal new.Texture = `rbxassetid://{texture_face}` new.Parent = part elseif texture_face_type == "table" then if texture_face.decal then local new = Instance.new("Decal") new.Texture = `rbxassetid://{texture_face[1]}` new.Face = normal new.Parent = part else local new = Instance.new("Texture") new.StudsPerTileU = texture_face.u or 3 new.StudsPerTileV = texture_face.v or 3 new.Face = normal new.Texture = `rbxassetid://{texture_face[1]}` new.Parent = part end end end end end end block.Parent = script block:PivotTo(CFrame.new(position) * rotation) end owner.Chatted:Connect(function(m) local args = m:split("/") if args[1] == "minecraft" then if args[2] == "new_block" then if args[3] == "help" then print("minecraft/new_block/full/~0 ~1 ~0/0 0 0/oak_block") return end local playerpos = owner.Character.Head.Position local rx, ry, rz = table.unpack(args[5]:split(" ")) local x, y, z = table.unpack(args[4]:split(" ")) local function parse_localpos(x, y, z, b) local xsplit = x:split("~") local ysplit = y:split("~") local zsplit = z:split("~") local p = Vector3.new(x, y, z) if xsplit[2] then p += Vector3.new(b.X, 0, 0) end if ysplit[2] then p += Vector3.new(0, b.Y, 0) end if zsplit[2] then p += Vector3.new(0, 0, b.Z) end return p end local pos = parse_localpos(x, y, z, playerpos) new_block(BLOCK_DATA[args[3]],pos, CFrame.Angles(math.rad(rx),math.rad(ry),math.rad(rz)),BLOCK_TEXTURES[args[6]]) end end end) do local t = Instance.new("Tool", owner.Backpack) local rem = Instance.new("RemoteFunction", t) NLS([[local uis = game:GetService"UserInputService" script.Parent.OnClientInvoke = function() local loc = uis:GetMouseLocation() local r = workspace.CurrentCamera:ViewportPointToRay(loc.X, loc.Y) local result = workspace:Raycast(r.Origin, r.Direction * 1000) return result and (result.Position + result.Normal), r.Origin end]], rem) t.Name = "new_block" local shape = BLOCK_DATA.full local tex = BLOCK_TEXTURES.oak_block t.RequiresHandle = false t.Activated:Connect(function() local pos, origin = rem:InvokeClient(owner) if pos then local rot = CFrame.lookAt(pos, origin) local rx, ry, rz = rot:ToEulerAnglesXYZ() local rightangle = math.pi / 2 new_block(shape, pos, CFrame.Angles(math.round(rx / rightangle) * rightangle,math.round(ry / rightangle) * rightangle,math.round(rz / rightangle) * rightangle) * CFrame.Angles(0, -rightangle, 0), tex) end end) owner.Chatted:Connect(function(m) local args = m:split("/") if args[1] == "shape" then shape = BLOCK_DATA[args[2]] end if args[1] == "tex" then tex = BLOCK_TEXTURES[args[2]] end end) end do local t = Instance.new("Tool", owner.Backpack) local rem = Instance.new("RemoteFunction", t) NLS([[local uis = game:GetService"UserInputService" script.Parent.OnClientInvoke = function() local loc = uis:GetMouseLocation() local r = workspace.CurrentCamera:ViewportPointToRay(loc.X, loc.Y) local result = workspace:Raycast(r.Origin, r.Direction * 1000) return result and result.Instance end]], rem) t.Name = "remove_block" t.RequiresHandle = false t.Activated:Connect(function() local target = rem:InvokeClient(owner) if target then if target:GetAttribute("BLOCK_MESH_PART") then target.Parent:Destroy() end end end) end